package com.cdxy.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cdxy.dmr.dataObject.HotelAttrDO;
import com.cdxy.dmr.dataObject.HotelDO;
import com.cdxy.dmr.dataObject.HotelRoomDO;
import com.cdxy.dmr.repository.HotelAttrRepository;
import com.cdxy.dmr.repository.HotelRepository;
import com.cdxy.dmr.repository.HotelRoomRepository;
import com.cdxy.enums.BizErrorEnum;
import com.cdxy.enums.SaveTypeEnum;
import com.cdxy.model.dto.base.exception.BusinessException;
import com.cdxy.model.dto.base.resp.BasePageResp;
import com.cdxy.model.dto.req.HotelDetailReq;
import com.cdxy.model.dto.req.SearchHotelReq;
import com.cdxy.model.dto.resp.HotelDetailResp;
import com.cdxy.model.dto.resp.ImgResp;
import com.cdxy.model.dto.resp.SearchHotelResp;
import com.cdxy.model.info.*;
import com.cdxy.service.IHotSearchService;
import com.cdxy.service.IHotelService;
import com.cdxy.service.IUserSaveService;
import com.cdxy.util.BeanUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 酒店表 服务实现类
 * </p>
 *
 * @author autoGenCode
 * @since 2020-03-05
 */
@Service
public class HotelServiceImpl implements IHotelService {

    @Autowired
    private HotelRepository hotelRepository;

    @Autowired
    private HotelAttrRepository hotelAttrRepository;

    @Autowired
    private HotelRoomRepository hotelRoomRepository;

    @Autowired
    private IUserSaveService userSaveService;

    @Autowired
    private IHotSearchService hotSearchService;

    @Override
    public BasePageResp<SearchHotelResp> searchHotel(SearchHotelReq searchHotelReq) {
        String city = searchHotelReq.getCity();
        Integer axUid = searchHotelReq.getAxUid();
        String search = searchHotelReq.getSearchContent();
        int size = searchHotelReq.getSize();
        int index = searchHotelReq.getIndex();


        IPage<HotelDO> iPageHotelDO = new Page<>(index, size);
        LambdaQueryWrapper<HotelDO> lambdaQueryWrapper = (new QueryWrapper<HotelDO>()).lambda();
        if (StringUtils.isNotBlank(city) && !city.equals("全国")) {
            lambdaQueryWrapper.eq(HotelDO::getCity, city);
            hotSearchService.searchOnce(city);
        }
        if (StringUtils.isNotBlank(search)) {
            lambdaQueryWrapper.and(obj -> obj.eq(HotelDO::getCity, search).or().eq(HotelDO::getName, search));
            hotSearchService.searchOnce(search);
        }
        iPageHotelDO = hotelRepository.page(iPageHotelDO, lambdaQueryWrapper);
        if (iPageHotelDO.getRecords().size() == 0) {
            iPageHotelDO = new Page<>(0, searchHotelReq.getSize());
            iPageHotelDO = hotelRepository.page(iPageHotelDO, lambdaQueryWrapper);
        }
        List<Integer> searchAddIdList = iPageHotelDO.getRecords().stream().map(HotelDO::getHotelId).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(searchAddIdList)) {
            hotelRepository.updateSearchNum(searchAddIdList);
        }

        List<SearchHotelResp> searchHotelRespList = BeanUtil.copyPropertiesByFastJson(iPageHotelDO.getRecords(), SearchHotelResp.class);
        BasePageResp<SearchHotelResp> basePageResp = BeanUtil.copyPropertiesByFastJson(iPageHotelDO, BasePageResp.class);
        basePageResp.setRecords(searchHotelRespList);

        if (axUid != null && searchHotelRespList.size() > 0) {
            List<Integer> ids = searchHotelRespList.stream().map(SearchHotelResp::getHotelId).collect(Collectors.toList());
            List<SaveInfo> saveInfoList = userSaveService.saveStatusList(ids, axUid, SaveTypeEnum.HOTEL);
            Map<Integer, SaveInfo> map = saveInfoList.stream().collect(Collectors.toMap(SaveInfo::getBusinessId, obj -> obj));
            searchHotelRespList.forEach(searchHotelResp -> {
                searchHotelResp.setIsSave(map.get(searchHotelResp.getHotelId()).getIsSave());
            });
        }

        basePageResp.setLastPage(size * index >= iPageHotelDO.getTotal());


        return basePageResp;
    }

    @Override
    public HotelDetailResp hotelDetail(HotelDetailReq hotelDetailReq) {
        Integer hotelId = hotelDetailReq.getHotelId();
        HotelDO hotelDO = hotelRepository.getById(hotelId);
        Integer axUid = hotelDetailReq.getAxUid();
        if (hotelDO == null) {
            throw new BusinessException(BizErrorEnum.HOTEL_NOT_EXIST);
        }
        HotelDetailResp hotelDetailResp = BeanUtil.copyPropertiesBySpring(hotelDO, HotelDetailResp.class);
        JSONObject policyObject = JSONObject.parseObject(hotelDO.getPolicy());
        JSONArray serviceArray = JSONArray.parseArray(hotelDO.getServices());
        JSONArray facilityArray = JSONArray.parseArray(hotelDO.getFacilities());

        if (axUid != null) {
            SaveInfo saveInfo = userSaveService.saveStatus(axUid, hotelId, SaveTypeEnum.HOTEL);
            hotelDetailResp.setIsSave(saveInfo.getIsSave());
        }

        HotelPolicyInfo policyInfo = BeanUtil.copyPropertiesByFastJson(policyObject, HotelPolicyInfo.class);
        hotelDetailResp.setHotelPolicyInfo(policyInfo);

        List<HotelServiceInfo> hotelServiceInfoList = new ArrayList<>(serviceArray.size());
        serviceArray.forEach(service -> {
            JSONObject jsonObject = JSON.parseObject(service.toString());
            HotelServiceInfo hotelServiceInfo = BeanUtil.copyPropertiesByFastJson(jsonObject, HotelServiceInfo.class);
            hotelServiceInfoList.add(hotelServiceInfo);
        });
        hotelDetailResp.setHotelServiceInfoList(hotelServiceInfoList);

        List<HotelFacilityInfo> hotelFacilityInfoList = new ArrayList<>(facilityArray.size());
        facilityArray.forEach(facility -> {
            JSONObject jsonObject = JSONObject.parseObject(facility.toString());
            HotelFacilityInfo hotelFacilityInfo = BeanUtil.copyPropertiesByFastJson(jsonObject, HotelFacilityInfo.class);
            hotelFacilityInfoList.add(hotelFacilityInfo);
        });
        hotelDetailResp.setFacilityInfoList(hotelFacilityInfoList);

        //img
        List<HotelAttrDO> hotelAttrDOList = hotelAttrRepository.listByHotelId(hotelId);
        List<ImgResp> hotelImgTopInfoList = BeanUtil.copyPropertiesByFastJson(hotelAttrDOList, ImgResp.class);
        hotelDetailResp.setImg(hotelImgTopInfoList);

        // 购票
        List<HotelRoomDO> hotelRoomDOList = hotelRoomRepository.listByHotelId(hotelId);
        List<HotelRoomInfo> hotelRoomInfoList = BeanUtil.copyPropertiesByFastJson(hotelRoomDOList, HotelRoomInfo.class);
        hotelDetailResp.setHotelRoomInfoList(hotelRoomInfoList);

        hotelRepository.updateSearchNum(hotelId);

        return hotelDetailResp;
    }
}
